package com.yzl.frelink.service.matlab;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.yzl.frelink.entities.chart.Parameter;
import com.yzl.frelink.entities.component.Chart;
import com.yzl.frelink.entities.model.Model;

@Service
public class ParameterCompiler {
    @Value("${frelink.paramCode}")
    public String paramcode;

    public String compileParameters(Model model) {
        int chartCount = 0;
        List<String> chartParams = new ArrayList<>();
        for (Chart chart : model.getCharts()) {
            chartCount++;
            StringBuilder sb = new StringBuilder();
            sb.append("names = [").append(compileNames(chart)).append("];\n");
            sb.append("types = [").append(compileTypes(chart)).append("];\n");
            sb.append("inits = [").append(compileInits(chart)).append("];\n");
            sb.append("scopes = [").append(compileScopes(chart)).append("];\n");
            sb.append("setParams(charts(").append(chartCount).append("), names, types, inits, scopes);\n");
            chartParams.add(sb.toString());
//             chartParams.add("""
// names = [%s];
// types = [%s];
// inits = [%s];
// scopes = [%s];
// setParams(charts(%d), names, types, inits, scopes);
// """.formatted(compileNames(chart), compileTypes(chart), compileInits(chart), compileScopes(chart), chartCount));
        }
//         return """
// %% create params
// %% set their type and/or initial in need
// function param = addParam(ch, name, type, init, scope)
//   param = Stateflow.Data(ch);
//   param.Name = name;
//   if type ~= 'null'
//     param.Props.Type.Method = "Built-in";
//     param.DataType = type;
//     if init ~= 'null'
//       param.Props.InitialValue = init;
//     end
//   end
//   param.Scope = scope;
// end

// function setParams(ch, names, types, inits, scopes)
//     mn = size(names);
//     nowSize = mn(2);
//     for i = 1 : nowSize
//         p(i) = addParam(ch, names(i), types(i), inits(i), scopes(i));
//     end
// end

// %s
// """.formatted(String.join("\n", chartParams));
        return paramcode + "\n" + String.join("\n", chartParams);
    }

    private static String compileNames(Chart chart) {
        List<String> names = new ArrayList<>();
        for (Parameter param : chart.getParameters()) {
            names.add("\"" + param.getName().replaceAll("\"", "") + "\"");
        }
        return String.join(", ", names);
    }    

    private static String compileTypes(Chart chart) {
        List<String> types = new ArrayList<>();
        for (Parameter param : chart.getParameters()) {
            types.add("\"" + param.getType() + "\"");
        }
        return String.join(", ", types);
    }

    private static String compileInits(Chart chart) {
        List<String> inits = new ArrayList<>();
        for (Parameter param : chart.getParameters()) {
            inits.add("\"" + param.getInitVal() + "\"");
        }
        return String.join(", ", inits);
    }

    private static String compileScopes(Chart chart) {
        List<String> scopes = new ArrayList<>();
        for (Parameter param : chart.getParameters()) {
            scopes.add("\"" + param.getScopeStr() + "\"");
        }
        return String.join(", ", scopes);
    }
}